﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Profile;
using System.Web.Security;
using Core.DAL;
using Core.Extentions;
using Core.Utils;

namespace Core.BOL
{
    public enum UserType
    {
        Administrator,
        Moderator,
        User
    }

    public class UsersRepository : IDisposable
    {
        private ScoutNetDataContext context = null;

        #region Construtor
        public UsersRepository()
        {
            context = GeneralUtils.GetDataContext();
        }
        #endregion

        #region Methodes
        public List<aspnet_User> GetUsersByListID(List<Guid> lUsersID)
        {
            var query = (from u in context.aspnet_Users
                         join m in context.aspnet_Memberships on u.UserId equals m.UserId
                         where lUsersID.Contains(u.UserId)
                         select u).ToList();

            return query;
        }

        public List<Guid> GetUserIdBySectionID(int sectionId)
        {
            List<Guid> lUserID = new List<Guid>();
            if (sectionId != 7)
            {
                lUserID = (from u in context.tSite_UsersSections
                           where u.SID == sectionId
                           select u.UID).ToList();
            }else{
                lUserID = (from u in context.tSite_UsersSections
                           select u.UID).ToList();
            }
            return lUserID;
        }

        public void InsertUsersSection(aspnet_User user)
        {
            foreach (int sectionID in user.SectionIDs)
            {
                tSite_UsersSection us = new tSite_UsersSection()
                {
                    UID = user.UserId,
                    SID = sectionID
                };
                context.tSite_UsersSections.InsertOnSubmit(us);
            }
        }

        public void UpdateSectionsByUserId(aspnet_User user)
        {
            context.tSite_UsersSections.DeleteAllOnSubmit(context.tSite_UsersSections.Where(p => p.UID == user.UserId).ToList());
            InsertUsersSection(user);
        }

        public static string GetAdminSection(string systemName)
        {
            MembershipUser mu = Membership.GetUser();
            if (mu != null)
            {
                string userRole = Roles.GetRolesForUser(mu.UserName).Take(1).SingleOrDefault();
                if (userRole == "Animateur")
                {
                    SectionRepository sr = new SectionRepository();
                    ProfileBase pb = ProfileBase.Create(mu.UserName);
                    tSite_Section s = sr.GetSectionsById(int.Parse(pb["SectionID"].ToString()));
                    return s.SystemName.UppercaseFirst();
                }
                else
                {
                    return systemName.UppercaseFirst();
                }
            }
            else
            {
                return null;
            }
        }

        public static UserType GetUserType()
        {
            string role;
            return GetUserType(string.Empty, out role);
        }

        public static UserType GetUserType(string currentSection)
        {
            string role;
            return GetUserType(currentSection, out role);
        }

        public static UserType GetUserType(string currentSection, out string role)
        {
            MembershipUser mu = Membership.GetUser();
            if (mu != null)
            {
                string userRole = Roles.GetRolesForUser(mu.UserName).Take(1).SingleOrDefault();
                role = userRole;
                UserType userType;
                switch (userRole.ToLower())
                {
                    case "animateur":
                        userType = UserType.Moderator;
                        break;
                    case "c.u":
                        userType = UserType.Administrator;
                        break;
                    default:
                        userType = UserType.User;
                        break;
                }

                if (userType == UserType.Moderator)
                {
                    ProfileBase pb = ProfileBase.Create(mu.UserName);
                    SectionRepository sr = new SectionRepository();
                    tSite_Section section = sr.GetSectionsById(int.Parse(pb["SectionID"].ToString()));

                    if (currentSection != string.Empty)
                    {
                        if (currentSection.ToLower() != section.SystemName.ToLower())
                        {
                            return UserType.User;
                        }
                        else
                        {
                            return UserType.Moderator;
                        }
                    }
                    else
                    {
                        return UserType.User;
                    }
                }
                else
                {
                    return userType;
                }
            }
            else
            {
                role = null;
                return UserType.User;
            }
        }

        public List<aspnet_User> SearchUsers(string userName)
        {
            var query = (from u in context.aspnet_Users
                         join up in context.tSite_UserProfiles on u.UserId equals up.UserId 
                         where u.UserName.Contains(userName) || up.FirstName.Contains(userName) || up.LastName.Contains(userName) && u.aspnet_Membership.IsApproved == true
                         select u).ToList();
             return query;
        }

        public List<aspnet_User> GetNotApprouvedUser()
        {
            var query = (from u in context.aspnet_Users
                         join m in context.aspnet_Memberships on u.UserId equals m.UserId
                         where m.IsApproved == false
                         select u).ToList();
            
            SectionRepository sr = new SectionRepository();
            List<tSite_Section> lSections = sr.GetAllSections();

            foreach (aspnet_User u in query)
            {
                ProfileBase pb = ProfileBase.Create(u.UserName);
                u.Lastname = pb["LastName"].ToString();
                u.Firstname = pb["FirstName"].ToString();

                int sectionID = -1;
                if (int.TryParse(pb["SectionID"].ToString(), out sectionID))
                {
                    tSite_Section s = lSections.Where(p => p.ID == sectionID).SingleOrDefault();
                    if (s != null)
                    {
                        u.SectionName = s.Section;
                    }
                }

                string role = Roles.GetRolesForUser(u.UserName)[0];
                u.Role = role;
            }

            return query;
        }

        public aspnet_User GetUserById(Guid userId)
        {
            var query = (from u in context.aspnet_Users
                         join m in context.tSite_UserProfiles on u.UserId equals m.UserId
                         where u.UserId == userId
                         select u).SingleOrDefault();
            return query;
        }

        public List<aspnet_User> GetUsersBySectionsAndFunction(string sectionIds, string functionIds)
        {
            string[] sectionID = sectionIds.Split(',');
            string[] functionID = functionIds.Split(',');
            List<Guid> lFunctionID = new List<Guid>();

            if (!string.IsNullOrEmpty(functionIds))
            {
                lFunctionID = new List<Guid>();
                foreach (var item in functionID)
                {
                    lFunctionID.Add(new Guid(item));
                }
            }

            if (!string.IsNullOrEmpty(sectionIds) && lFunctionID.Count() == 0)
            {
                var query = (from u in context.aspnet_Users
                            join m in context.tSite_UserProfiles on u.UserId equals m.UserId
                            join uir in context.aspnet_UsersInRoles on u.UserId equals uir.UserId
                            where sectionID.Contains(m.SectionID.ToString())
                            select u).ToList();
                return query;
            }
            else if (string.IsNullOrEmpty(sectionIds) && lFunctionID.Count() > 0)
            {
                var query = (from u in context.aspnet_Users
                             join m in context.tSite_UserProfiles on u.UserId equals m.UserId
                             join uir in context.aspnet_UsersInRoles on u.UserId equals uir.UserId
                             where lFunctionID.Contains(uir.RoleId)
                             select u).ToList();
                return query;
            }
            else
            {
                var query = (from u in context.aspnet_Users
                             join m in context.tSite_UserProfiles on u.UserId equals m.UserId
                             join uir in context.aspnet_UsersInRoles on u.UserId equals uir.UserId
                             where sectionID.Contains(m.SectionID.ToString()) && lFunctionID.Contains(uir.RoleId)
                             select u).ToList();
                return query;
            }
        }

        public void DeleteUserSections(Guid UID)
        {
            var query = (from s in context.tSite_UsersSections
                         join u in context.aspnet_Users on s.UID equals u.UserId
                         where u.UserId == UID
                         select s).ToList();
            
            if (query != null && query.Count > 0)
            {
                context.tSite_UsersSections.DeleteAllOnSubmit(query);
            }
        }

        internal void DeleteUser(string userName)
        {
            context.sp_Aspnet_DeleteUser(userName);
        }

        public void Save()
        {
            context.SubmitChanges();
        }

        public void Dispose()
        {
            context.Dispose();
        }
        #endregion
    }
}
